package com.ldf.media.callback;

import com.aizuda.zlm4j.callback.IMKNoReaderCallBack;
import com.aizuda.zlm4j.structure.MK_MEDIA_SOURCE;
import com.ldf.media.api.service.IApiService;
import com.ldf.media.context.MediaServerContext;
import com.sun.jna.CallbackThreadInitializer;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Map;

import static com.ldf.media.constants.MediaServerConstants.*;

/**
 * 无人观看回调
 *
 * @author lidaofu
 * @since 2023/11/23
 **/
@Slf4j
@Component
public class MKNoReaderCallBack implements IMKNoReaderCallBack, ApplicationContextAware {
    
    private ApplicationContext applicationContext;

    public MKNoReaderCallBack() {
        //回调使用同一个线程
        Native.setCallbackThreadInitializer(this, new CallbackThreadInitializer(true, false, "MediaNoReaderThread"));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 某个流无人消费时触发，目的为了实现无人观看时主动断开拉流等业务逻辑
     *
     * @param sender 该MediaSource对象
     */
    public void invoke(MK_MEDIA_SOURCE sender) {
        String streamId = buildStreamId(sender);
        
        // 记录流暂停播放的信息
        log.info("流 {} 暂停播放，检查是否需要关闭", streamId);
        
        // 检查是否是拉流代理创建的流，如果是则关闭
        int originType = MediaServerContext.ZLM_API.mk_media_source_get_origin_type(sender);
        // 拉流代理的originType为4 (参考ZLMediaKit文档)
        if (originType == 4) {
            String app = MediaServerContext.ZLM_API.mk_media_source_get_app(sender);
            String stream = MediaServerContext.ZLM_API.mk_media_source_get_stream(sender);
            log.info("检测到拉流代理流无人观看，准备关闭: {}/{}", app, stream);
            
            // 查找对应的拉流代理并关闭
            closeProxyStream(app, stream);
        }
    }

    /**
     * 构建唯一的流标识符
     */
    private String buildStreamId(MK_MEDIA_SOURCE source) {
        return String.format("%s/%s",
                MediaServerContext.ZLM_API.mk_media_source_get_app(source),
                MediaServerContext.ZLM_API.mk_media_source_get_stream(source));
    }
    
    /**
     * 关闭拉流代理流
     * @param app 应用名
     * @param stream 流名
     */
    private void closeProxyStream(String app, String stream) {
        // 获取拉流代理key
        IApiService apiService = applicationContext.getBean(IApiService.class);
        String proxyKey = apiService.getProxyKeyByStream(app, stream);
        if (proxyKey != null) {
            log.info("关闭拉流代理流: {}/{}, proxyKey: {}", app, stream, proxyKey);
            // 调用服务关闭拉流代理
            apiService.delStreamProxy(proxyKey);
        } else {
            log.warn("未找到拉流代理流的proxyKey: {}/{}", app, stream);
        }
    }
}